package com.tust.androidbbsclient.fragment;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.tust.androidbbsclient.R;
import com.tust.androidbbsclient.adapter.MessageMsgListRecyclerAdapter;
import com.tust.androidbbsclient.tool.Application;
import com.tust.androidbbsclient.tool.Tool;
import com.tust.androidbbsclient.trans.MessageList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link MessageFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class MessageFragment extends Fragment {
    private Toast toast;
    private Context context;
    private int MsgReceiver;
    private List<MessageList> messageLists;

    RecyclerView recyclerViewMessageMsgList;
    MessageMsgListRecyclerAdapter messageMsgListRecyclerAdapter;

    //用于在线程间传递消息
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);//获取子线程传递的消息
            if (msg.what == 1) {//查询所有管理员和用户消息列表请求子线程返回值
                String strMsg = msg.obj.toString();
                //System.out.println("查询评论列表：" + strMsg);

                if (strMsg.equals("serverFalse")) showToast(Tool.addEmoji() + "服务器通信失败！");
                else setRecyclerView(strMsg);//调用RecyclerView设置方法
            } else if (msg.what == 2) {//分页下一页请求返回值
                String strMsg = msg.obj.toString();
                //System.out.println("分页下一页：" + strMsg);

                if (strMsg.equals("serverFalse")) showToast(Tool.addEmoji() + "服务器通信失败！");
                else addRecyclerViewItem(strMsg);//调用RecyclerView设置方法
            }
        }
    };

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public MessageFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment MessageFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static MessageFragment newInstance(String param1, String param2) {
        MessageFragment fragment = new MessageFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_message, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        context = getContext();

        recyclerViewMessageMsgList = view.findViewById(R.id.rv_messageMsgList);
        Button buttonMessageAdminMsgList = view.findViewById(R.id.btn_messageAdminMsgList);
        Button buttonMessageUserMsgList = view.findViewById(R.id.btn_messageUserMsgList);
        FloatingActionButton floatingActionButtonMessageMsgList = view.findViewById(R.id.fab_messageMsgList);

        //从Application中获得用户信息
        Application application = (Application) getActivity().getApplication();
        MsgReceiver = application.user.getUID();

        buttonMessageAdminMsgList.setBackgroundColor(ContextCompat.getColor(context, R.color.sandybrown));//默认展示管理员消息
        buttonMessageUserMsgList.setBackgroundColor(ContextCompat.getColor(context, R.color.powderblue));

        //发送查询所有管理员消息列表请求子线程
        new Thread() {
            @Override
            public void run() {
                OutputStream outputStream = null;
                BufferedReader bufferedReader = null;
                String data = "";
                try {
                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                    handlerMsg.what = 1;//增加handlerMsg标识符

                    URL url = new URL(Tool.InetAddress + "/searchAllAdminMsgList.do");//请求地址
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                    //连接类相关设置
                    connection.setRequestMethod("POST");
                    connection.setConnectTimeout(5000);//连接服务器超时
                    connection.setReadTimeout(5000);//从服务器读取数据超时
                    connection.setDoInput(true);//允许写入，从服务端读取结果流
                    connection.setDoOutput(true);//允许写出，开启Post请求体
                    connection.setUseCaches(false);//不使用Cache
                    connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式

                    connection.connect();//连接网络
                    String params = "MsgReceiver=" + MsgReceiver;//请求体内容
                    outputStream = connection.getOutputStream();//请求输出流
                    outputStream.write(params.getBytes());

                    int code = connection.getResponseCode();//获得响应状态码
                    if (code == 200) {//返回状态码200，连接成功
                        bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                        data = bufferedReader.readLine();

                        handlerMsg.obj = data;//写入线程传递消息
                    } else handlerMsg.obj = "serverFalse";//服务器通信失败
                    connection.disconnect();//关闭连接

                    handler.sendMessage(handlerMsg);//发送线程消息
                } catch (IOException e) {
                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                    handlerMsg.what = 1;//增加handlerMsg标识符
                    handlerMsg.obj = "serverFalse";
                    handler.sendMessage(handlerMsg);

                    //throw new RuntimeException(e);
                } finally {
                    try {
                        if (bufferedReader != null) bufferedReader.close();
                        if (outputStream != null) {
                            outputStream.flush();
                            outputStream.close();
                        }
                    } catch (IOException e) {
                        System.out.println("子线程：finally失败");
                        //throw new RuntimeException(e);
                    }
                }
            }
        }.start();

        //通告按钮监听事件
        buttonMessageAdminMsgList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //改变按钮颜色
                buttonMessageAdminMsgList.setBackgroundColor(ContextCompat.getColor(context, R.color.sandybrown));
                buttonMessageUserMsgList.setBackgroundColor(ContextCompat.getColor(context, R.color.powderblue));

                //发送查询所有管理员消息列表请求子线程
                new Thread() {
                    @Override
                    public void run() {
                        OutputStream outputStream = null;
                        BufferedReader bufferedReader = null;
                        String data = "";
                        try {
                            Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                            handlerMsg.what = 1;//增加handlerMsg标识符

                            URL url = new URL(Tool.InetAddress + "/searchAllAdminMsgList.do");//请求地址
                            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                            //连接类相关设置
                            connection.setRequestMethod("POST");
                            connection.setConnectTimeout(5000);//连接服务器超时
                            connection.setReadTimeout(5000);//从服务器读取数据超时
                            connection.setDoInput(true);//允许写入，从服务端读取结果流
                            connection.setDoOutput(true);//允许写出，开启Post请求体
                            connection.setUseCaches(false);//不使用Cache
                            connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式

                            connection.connect();//连接网络
                            String params = "MsgReceiver=" + MsgReceiver;//请求体内容
                            outputStream = connection.getOutputStream();//请求输出流
                            outputStream.write(params.getBytes());

                            int code = connection.getResponseCode();//获得响应状态码
                            if (code == 200) {//返回状态码200，连接成功
                                bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                data = bufferedReader.readLine();

                                handlerMsg.obj = data;//写入线程传递消息
                            } else handlerMsg.obj = "serverFalse";//服务器通信失败
                            connection.disconnect();//关闭连接

                            handler.sendMessage(handlerMsg);//发送线程消息
                        } catch (IOException e) {
                            Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                            handlerMsg.what = 1;//增加handlerMsg标识符
                            handlerMsg.obj = "serverFalse";
                            handler.sendMessage(handlerMsg);

                            //throw new RuntimeException(e);
                        } finally {
                            try {
                                if (bufferedReader != null) bufferedReader.close();
                                if (outputStream != null) {
                                    outputStream.flush();
                                    outputStream.close();
                                }
                            } catch (IOException e) {
                                System.out.println("子线程：finally失败");
                                //throw new RuntimeException(e);
                            }
                        }
                    }
                }.start();
            }
        });

        //消息按钮监听事件
        buttonMessageUserMsgList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //改变按钮颜色
                buttonMessageAdminMsgList.setBackgroundColor(ContextCompat.getColor(context, R.color.powderblue));
                buttonMessageUserMsgList.setBackgroundColor(ContextCompat.getColor(context, R.color.sandybrown));

                //发送查询所有用户消息列表请求子线程
                new Thread() {
                    @Override
                    public void run() {
                        OutputStream outputStream = null;
                        BufferedReader bufferedReader = null;
                        String data = "";
                        try {
                            Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                            handlerMsg.what = 1;//增加handlerMsg标识符

                            URL url = new URL(Tool.InetAddress + "/searchAllUserMsgList.do");//请求地址
                            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                            //连接类相关设置
                            connection.setRequestMethod("POST");
                            connection.setConnectTimeout(5000);//连接服务器超时
                            connection.setReadTimeout(5000);//从服务器读取数据超时
                            connection.setDoInput(true);//允许写入，从服务端读取结果流
                            connection.setDoOutput(true);//允许写出，开启Post请求体
                            connection.setUseCaches(false);//不使用Cache
                            connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式

                            connection.connect();//连接网络
                            String params = "MsgReceiver=" + MsgReceiver;//请求体内容
                            outputStream = connection.getOutputStream();//请求输出流
                            outputStream.write(params.getBytes());

                            int code = connection.getResponseCode();//获得响应状态码
                            if (code == 200) {//返回状态码200，连接成功
                                bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                data = bufferedReader.readLine();

                                handlerMsg.obj = data;//写入线程传递消息
                            } else handlerMsg.obj = "serverFalse";//服务器通信失败
                            connection.disconnect();//关闭连接

                            handler.sendMessage(handlerMsg);//发送线程消息
                        } catch (IOException e) {
                            Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                            handlerMsg.what = 1;//增加handlerMsg标识符
                            handlerMsg.obj = "serverFalse";
                            handler.sendMessage(handlerMsg);

                            //throw new RuntimeException(e);
                        } finally {
                            try {
                                if (bufferedReader != null) bufferedReader.close();
                                if (outputStream != null) {
                                    outputStream.flush();
                                    outputStream.close();
                                }
                            } catch (IOException e) {
                                System.out.println("子线程：finally失败");
                                //throw new RuntimeException(e);
                            }
                        }
                    }
                }.start();
            }
        });

        //RecyclerView滚动监听事件
        recyclerViewMessageMsgList.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            //滚动到底部时
            if (!recyclerView.canScrollVertically(1)) {
                //showToast(Tool.addEmoji() + "已到达底部！");

                //发送分页下一页请求子线程
                new Thread() {
                    @Override
                    public void run() {
                        BufferedReader bufferedReader = null;
                        String data = "";
                        try {
                            Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                            handlerMsg.what = 2;//增加handlerMsg标识符

                            URL url = new URL(Tool.InetAddress + "/nextMessageListPage.do");//请求地址
                            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                            //连接类相关设置
                            connection.setRequestMethod("POST");
                            connection.setConnectTimeout(5000);//连接服务器超时
                            connection.setReadTimeout(5000);//从服务器读取数据超时
                            connection.setDoInput(true);//允许写入，从服务端读取结果流
                            connection.setDoOutput(true);//允许写出，开启Post请求体
                            connection.setUseCaches(false);//不使用Cache
                            connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式

                            connection.connect();//连接网络

                            int code = connection.getResponseCode();//获得响应状态码
                            if (code == 200) {//返回状态码200，连接成功
                                bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                data = bufferedReader.readLine();

                                handlerMsg.obj = data;//写入线程传递消息
                            } else handlerMsg.obj = "serverFalse";//服务器通信失败
                            connection.disconnect();//关闭连接

                            handler.sendMessage(handlerMsg);//发送线程消息
                        } catch (IOException e) {
                            Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                            handlerMsg.what = 2;//增加handlerMsg标识符
                            handlerMsg.obj = "serverFalse";
                            handler.sendMessage(handlerMsg);

                            //throw new RuntimeException(e);
                        } finally {
                            try {
                                if (bufferedReader != null) bufferedReader.close();
                            } catch (IOException e) {
                                System.out.println("子线程：finally失败");
                                //throw new RuntimeException(e);
                            }
                        }
                    }
                }.start();
            }
            }
        });

        //悬浮按钮监听事件
        floatingActionButtonMessageMsgList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                recyclerViewMessageMsgList.smoothScrollToPosition(0);//平滑滚动到顶部
            }
        });
    }

    //设置RecyclerView
    private void setRecyclerView(String msgListData) {
        messageLists = new ArrayList<>();
        //解析JSON字符串
        try {
            JSONArray jsonArray = new JSONArray(msgListData);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                messageLists.add(
                        new MessageList(
                                Integer.parseInt(jsonObject.getString("msgID")),
                                jsonObject.getString("msgSenderName"),
                                jsonObject.getString("msgContent"),
                                Integer.parseInt(jsonObject.getString("artID")),
                                jsonObject.getString("msgTime"),
                                Integer.parseInt(jsonObject.getString("msgIsReaded"))
                        )
                );
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

        if (messageLists.size() > 0) showToast(Tool.addEmoji() + "已请求到数据，正在加载！");
        else showToast(Tool.addEmoji() + "没有消息！");

        messageMsgListRecyclerAdapter = new MessageMsgListRecyclerAdapter(context, this, messageLists);//构造Recycler适配器
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);//创建线性布局管理器,默认子项布局垂直方向
        linearLayoutManager.setReverseLayout(false);//子项布局从顶部开始排列
        recyclerViewMessageMsgList.setLayoutManager(linearLayoutManager);//为RecyclerView设置布局管理器
        recyclerViewMessageMsgList.setAdapter(messageMsgListRecyclerAdapter);//为RecyclerView设置适配器
    }

    //动态增加RecyclerView子项
    private void addRecyclerViewItem(String addMsgListData) {
        List<MessageList> addMessageLists = new ArrayList<>();//增加的消息列表
        //解析JSON字符串
        try {
            JSONArray jsonArray = new JSONArray(addMsgListData);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                addMessageLists.add(
                        new MessageList(
                                Integer.parseInt(jsonObject.getString("msgID")),
                                jsonObject.getString("msgSenderName"),
                                jsonObject.getString("msgContent"),
                                Integer.parseInt(jsonObject.getString("artID")),
                                jsonObject.getString("msgTime"),
                                Integer.parseInt(jsonObject.getString("msgIsReaded"))
                        )
                );
            }
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }

        messageLists.addAll(addMessageLists);
        if (addMessageLists.size() > 0) showToast(Tool.addEmoji() + "正在加载更多！");
        else showToast(Tool.addEmoji() + "已全部加载完成！");

        //动态增加RecyclerView子项
        messageMsgListRecyclerAdapter.notifyItemRangeInserted(messageLists.size() - addMessageLists.size(), addMessageLists.size());
    }

    //Toast消息提示框显示方法
    private void showToast(String s) {
        if (toast == null){
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
        }else {
            toast.cancel();
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
        }
        toast.show();
    }
}
